package com.aurora.advanced;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.cookie.DefaultCookieSpec;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClientBuilder;

/**
 * 描述：客户端配置
 * 允许在创建 CloseableHttpClient 实例时进行额外的 HTTP 客户端配置
 *
 * @author 浅夏的猫
 * @version 1.0.0
 * @date 2024-02-13 23:28:15
 */
public class CustomHttpClientConfigCallback implements RestClientBuilder.HttpClientConfigCallback {

    private ElasticsearchEntity elasticsearchEntity;

    CustomHttpClientConfigCallback(ElasticsearchEntity elasticsearchEntity) {
        this.elasticsearchEntity = elasticsearchEntity;
    }

    /**
     * 描述：自定义客户端Http请求回调参数配置
     *
     * @param httpAsyncClientBuilder 参数建造器
     * @return {@code HttpAsyncClientBuilder }
     */
    @Override
    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {

        RequestConfig.Builder custom = RequestConfig.custom();
        // 设置与 Elasticsearch 集群建立连接的超时时间，单位为毫秒。在指定的时间内无法建立连接将会抛出连接超时异常
        custom.setConnectTimeout(elasticsearchEntity.getConnectTimeout());
        // 设置与 Elasticsearch 连接的套接字超时时间，单位为毫秒。该参数定义了在建立连接后从服务器读取数据的超时时间。如果在指定的时间内没有读取到数据，将会抛出超时异常。
        custom.setSocketTimeout(elasticsearchEntity.getSocketTimeout());
        // 设置连接请求超时时间，单位为毫秒。该参数表示从连接池获取连接的超时时间。如果在指定的时间内无法获得连接，将会抛出连接请求超时异常。
        custom.setConnectionRequestTimeout(elasticsearchEntity.getConnectionRequestTimeout());

        // 设置是否允许重定向。如果设置为true，则当遇到重定向响应时，客户端将跟随重定向并继续请求；如果设置为false，重定向响应将被视为错误。
        custom.setRedirectsEnabled(elasticsearchEntity.getRedirectsEnabled());
        // 设置最大重定向次数。当允许重定向时，该参数指定在遇到重定向响应时，最多可以重定向的次数。
        custom.setMaxRedirects(elasticsearchEntity.getMaxRedirects());

        // 启用身份验证功能。通过设置该参数为true，可以提供用户名和密码进行身份验证，以连接到 Elasticsearch 集群。
        custom.setAuthenticationEnabled(elasticsearchEntity.getAuthenticationEnabled());
        // 设置是否允许循环重定向。如果设置为true，则允许在重定向过程中发生循环重定向；如果设置为false，则在检测到循环重定向时，将会抛出异常。
        custom.setCircularRedirectsAllowed(elasticsearchEntity.getCircularRedirectsAllowed());
        // 设置是否启用内容压缩。如果设置为true，则允许客户端和 Elasticsearch 之间进行内容压缩，以减少数据传输量。
        custom.setContentCompressionEnabled(elasticsearchEntity.getContentCompressionEnabled());
        // 设置是否启用 "Expect: continue" 机制。当设置为true时，在发送请求之前，客户端会发送一个请求头部，询问服务器是否接受请求的主体部分。
        //  如果服务器响应允许继续发送请求主体，则客户端会继续发送请求；如果服务器响应拒绝继续发送请求主体，则客户端会放弃该请求。
        custom.setExpectContinueEnabled(elasticsearchEntity.getExpectContinueEnabled());

        // 设置是否标准化 URI。如果设置为true，则客户端会尝试标准化请求 URI，以便消除多余和重复的斜杠等。
        custom.setNormalizeUri(elasticsearchEntity.getNormalizeUri());
        // 设置使用的 Cookie 规范。可以指定客户端在处理与 Elasticsearch 服务器之间的 Cookie 交互时使用的 Cookie 规范
        custom.setCookieSpec(new DefaultCookieSpec().toString());

        return httpAsyncClientBuilder.setDefaultRequestConfig(custom.build());
    }
}
